package com.ozo.boot.common.base.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 *
 * @author qiangesoft
 * @date 2024-05-23
 */
public class DateUtils {

    public static final String[] CHINESE_WEEK_DAY = new String[]{"周一", "周二", "周三", "周四", "周五", "周六", "周日"};

    /**
     * 显示到日期
     */
    public static final String FORMAT_DATE = "yyyy-MM-dd";
    /**
     * 显示到小时
     */
    public static final String FORMAT_HOUR = "yyyy-MM-dd HH";
    /**
     * 显示到分
     */
    public static final String FORMAT_MINUTE = "yyyy-MM-dd HH:mm";
    /**
     * 显示到秒
     */
    public static final String FORMAT_SECOND = "yyyy-MM-dd HH:mm:ss";
    /**
     * 显示到毫秒
     */
    public static final String FORMAT_MILLISECOND = "yyyy-MM-dd HH:mm:ss:SSS";
    /**
     * 数字格式显示到日期
     */
    public static final String FORMAT_DATE_NUMBER = "yyyyMMdd";
    /**
     * 数字格式显示到小时
     */
    public static final String FORMAT_HOUR_NUMBER = "yyyyMMddHH";
    /**
     * 数字格式显示到分
     */
    public static final String FORMAT_MINUTE_NUMBER = "yyyyMMddHHmm";
    /**
     * 数字格式显示到秒
     */
    public static final String FORMAT_SECOND_NUMBER = "yyyyMMddHHmmss";
    /**
     * 数字格式显示到毫秒
     */
    public static final String FORMAT_MILLISECOND_NUMBER = "yyyyMMddHHmmssSSS";

    /**
     * 当前时间
     *
     * @return
     */
    public static Date now() {
        return new Date();
    }

    /**
     * 当日的开始时间
     *
     * @return
     */
    public static Date startOfDay() {
        return startOfDay(now());
    }

    /**
     * 某天的开始时间
     *
     * @param date
     * @return
     */
    public static Date startOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 当日的结束时间
     *
     * @return
     */
    public static Date endOfDay() {
        return endOfDay(now());
    }

    /**
     * 某天的结束时间
     *
     * @param date
     * @return
     */
    public static Date endOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 本周第几天
     *
     * @return
     */
    public static int dayOfWeek() {
        return dayOfWeek(now());
    }

    /**
     * 某周第几天
     *
     * @param date
     * @return
     */
    public static int dayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayNum = calendar.get(Calendar.DAY_OF_WEEK);
        return dayNum == 1 ? 7 : dayNum - 1;
    }

    /**
     * 本周星期几
     *
     * @return
     */
    public static String dayNameOfWeek() {
        return dayNameOfWeek(now());
    }

    /**
     * 某周星期几
     *
     * @param date
     * @return
     */
    public static String dayNameOfWeek(Date date) {
        int dayNum = dayOfWeek(date);
        return CHINESE_WEEK_DAY[dayNum - 1];
    }

    /**
     * 本周的开始时间
     *
     * @return
     */
    public static Date startOfWeek() {
        return startOfWeek(now());
    }

    /**
     * 某周的开始时间
     *
     * @param date
     * @return
     */
    public static Date startOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 本周的结束时间
     *
     * @return
     */
    public static Date endOfWeek() {
        return endOfWeek(now());
    }

    /**
     * 某周的结束时间
     *
     * @param date
     * @return
     */
    public static Date endOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        calendar.add(Calendar.WEEK_OF_YEAR, 1);
        return calendar.getTime();
    }

    /**
     * 当月开始时间
     *
     * @return
     */
    public static Date startOfMonth() {
        return startOfMonth(now());
    }

    /**
     * 某月开始时间
     *
     * @param date
     * @return
     */
    public static Date startOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 当月结束时间
     *
     * @return
     */
    public static Date endOfMonth() {
        return endOfMonth(now());
    }

    /**
     * 某月结束时间
     *
     * @param date
     * @return
     */
    public static Date endOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 当年开始时间
     *
     * @return
     */
    public static Date startOfYear() {
        return startOfYear(now());
    }

    /**
     * 某年开始时间
     *
     * @param date
     * @return
     */
    public static Date startOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 当年结束时间
     *
     * @return
     */
    public static Date endOfYear() {
        return endOfYear(now());
    }

    /**
     * 某年结束时间
     *
     * @param date
     * @return
     */
    public static Date endOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMaximum(Calendar.DAY_OF_YEAR));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 当日是否属于时间范围内
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static Boolean between(Date startTime, Date endTime) {
        return between(now(), startTime, endTime);
    }

    /**
     * 时间范围内
     *
     * @param date
     * @param startTime
     * @param endTime
     * @return
     */
    public static Boolean between(Date date, Date startTime, Date endTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Calendar start = Calendar.getInstance();
        start.setTime(startTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        return calendar.after(start) && calendar.before(end);
    }

    /**
     * 时间格式化
     *
     * @param date
     * @return
     */
    public static String format(Date date) {
        return format(date, FORMAT_SECOND);
    }

    /**
     * 时间格式化
     *
     * @param date
     * @param format
     * @return
     */
    public static String format(Date date, String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    /**
     * 字符串转时间
     *
     * @param date
     * @param format
     * @return
     */
    public static Date parse(String date, String format) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.parse(date);
    }

    /**
     * 增加秒
     *
     * @param second
     * @return
     */
    public static Date addSecond(int second) {
        return addSecond(now(), second);
    }

    /**
     * 增加秒
     *
     * @param date
     * @param second
     * @return
     */
    public static Date addSecond(Date date, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, second);
        return calendar.getTime();
    }

    /**
     * 增加分钟
     *
     * @param minute
     * @return
     */
    public static Date addMinute(int minute) {
        return addMinute(now(), minute);
    }

    /**
     * 增加分钟
     *
     * @param date
     * @param minute
     * @return
     */
    public static Date addMinute(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 增加小时
     *
     * @param hour
     * @return
     */
    public static Date addHour(int hour) {
        return addHour(now(), hour);
    }

    /**
     * 增加小时
     *
     * @param date
     * @param hour
     * @return
     */
    public static Date addHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hour);
        return calendar.getTime();
    }

    /**
     * 增加天
     *
     * @param day
     * @return
     */
    public static Date addDay(int day) {
        return addDay(day);
    }

    /**
     * 增加天
     *
     * @param date
     * @param day
     * @return
     */
    public static Date addDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 增加周
     *
     * @param week
     * @return
     */
    public static Date addWeek(int week) {
        return addWeek(now(), week);
    }

    /**
     * 增加周
     *
     * @param date
     * @param week
     * @return
     */
    public static Date addWeek(Date date, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.WEEK_OF_YEAR, week);
        return calendar.getTime();
    }

    /**
     * 增加月
     *
     * @param month
     * @return
     */
    public static Date addMonth(int month) {
        return addMonth(now(), month);
    }

    /**
     * 增加月
     *
     * @param date
     * @param month
     * @return
     */
    public static Date addMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }

    /**
     * 增加年
     *
     * @param year
     * @return
     */
    public static Date addYear(int year) {
        return addYear(now(), year);
    }

    /**
     * 增加年
     *
     * @param date
     * @param year
     * @return
     */
    public static Date addYear(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 减少秒
     *
     * @param second
     * @return
     */
    public static Date reduceSecond(int second) {
        return reduceSecond(now(), second);
    }

    /**
     * 减少秒
     *
     * @param date
     * @param second
     * @return
     */
    public static Date reduceSecond(Date date, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, -second);
        return calendar.getTime();
    }

    /**
     * 减少分钟
     *
     * @param minute
     * @return
     */
    public static Date reduceMinute(int minute) {
        return reduceMinute(now(), minute);
    }

    /**
     * 减少分钟
     *
     * @param date
     * @param minute
     * @return
     */
    public static Date reduceMinute(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, -minute);
        return calendar.getTime();
    }

    /**
     * 减少小时
     *
     * @param hour
     * @return
     */
    public static Date reduceHour(int hour) {
        return reduceHour(now(), hour);
    }

    /**
     * 减少小时
     *
     * @param date
     * @param hour
     * @return
     */
    public static Date reduceHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, -hour);
        return calendar.getTime();
    }

    /**
     * 减少天
     *
     * @param day
     * @return
     */
    public static Date reduceDay(int day) {
        return reduceDay(now(), day);
    }

    /**
     * 减少天
     *
     * @param date
     * @param day
     * @return
     */
    public static Date reduceDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -day);
        return calendar.getTime();
    }

    /**
     * 减少周
     *
     * @param week
     * @return
     */
    public static Date reduceWeek(int week) {
        return reduceWeek(now(), week);
    }

    /**
     * 减少周
     *
     * @param date
     * @param week
     * @return
     */
    public static Date reduceWeek(Date date, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.WEEK_OF_YEAR, -week);
        return calendar.getTime();
    }

    /**
     * 减少月
     *
     * @param month
     * @return
     */
    public static Date reduceMonth(int month) {
        return reduceMonth(now(), month);
    }

    /**
     * 减少月
     *
     * @param date
     * @param month
     * @return
     */
    public static Date reduceMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -month);
        return calendar.getTime();
    }

    /**
     * 减少年
     *
     * @param year
     * @return
     */
    public static Date reduceYear(int year) {
        return reduceYear(now(), year);
    }

    /**
     * 减少年
     *
     * @param date
     * @param year
     * @return
     */
    public static Date reduceYear(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, -year);
        return calendar.getTime();
    }

}

